#
# "@(#) $Id: LGetMultiInfoDialog.py,v 1.1.1.1 2006-07-27 03:16:08 gioshe Exp $"
#
# This work is released under the GNU GPL, version 2 or later.
#
from Utils.kdeemul import *
from Utils.musicgenres import *
from Utils.presets import *
import sys
from RatingWidget import *
from Utils.utils import *
from DB.Library import Library
from Utils.amazon import *
from Utils.Paths import art
from ArtworkWindow import *


def fittedPixmap(pixmap,width,height):
	pixSize = pixmap.size()
	pw = pixSize.width()
	ph = pixSize.height()
	if pw==0: pw = 1
	if ph==0: ph = 1
	scaleX = 1.0*width/pw
	scaleY = 1.0*height/ph
	scale = scaleX
	if scaleX>scaleY:
		scale = scaleY
	if scale>1.0:
		scale = 1.0
	mat = QWMatrix()
	mat.scale(scale,scale)
	newpix = pixmap.xForm(mat)
	return newpix

class ArtLabel(QLabel):
	_validExtensions = ['.jpg','.png']

	def __init__(self,container,name=''):
		#KIconView.__init__(self,container,name)
		QLabel.__init__(self,container,name)
		self.container=container
		self.changed=None
		self.setAcceptDrops(True)
		self.default=True
		#self.setAcceptDrags(True)

	def canImportFile(self,filePath):
		if os.path.exists(str(filePath)):
			if os.path.isdir(str(filePath)):
				return False
			else:
				ext = os.path.splitext(str(filePath))[1]
				if ext in self._validExtensions:
					return True
		return False

	def canImportFiles(self,uris):
		for uri in uris:
			if self.canImportFile(uri):
				return True
		return False

	def dragEnterEvent(self,event):
		print "drag enter"
		if QUriDrag.canDecode(event):
			uris = QStringList()
			if QUriDrag.decodeLocalFiles(event,uris):
				if self.canImportFiles(uris):
					event.accept(True)

	def dropEvent(self,event):
		print "dropped remote drag on art"
		uris = QStringList()
		if QUriDrag.decodeLocalFiles(event,uris):
			for uri in uris:
				pixmap=QPixmap(uri)
				f=open(unikode(uri))
				self.changed=f.read()
				f.close()
				self.setPixmap(fittedPixmap(pixmap,110,110))
				rem=self.container.child('remBtn')
				check=self.container.child('artChck')
				rem.setEnabled(True)
				check.setChecked(True)
				self.default=False
				return
##	#need to change the class to work better and use real size of the image
##	def mouseDoubleClickEvent(self,ev):
##		if not self.default:
##			self.art = ArtworkWindow(self.pixmap()s,'Album Artwork Preview')
##		
	def getImg(self):
		return self.changed
	def setImg(self,set=None):
		self.changed=set
		self.default=False
	img=property(getImg,setImg)

	
class LGetMultiInfoCheckBox(QCheckBox):
	def __init__(self,container):
		QCheckBox.__init__(self,container)
	
	def setLineEditItem(self,item):
		QObject.connect(item,SIGNAL("textChanged(const QString &)"),self.itemChanged)
	
	def setSpinEditItem(self,item):
		QObject.connect(item,SIGNAL("valueChanged(const QString &)"),self.itemChanged)
	
	def setComboBoxItem(self,item):
		QObject.connect(item,SIGNAL("activated(const QString &)"),self.itemChanged)

	def setSliderItem(self,item):
		QObject.connect(item,SIGNAL("valueChanged(int)"),self.itemChanged)
	
	def setRatingItem(self,item):
		QObject.connect(item,PYSIGNAL("ratingChanged"),self.itemChanged)

	def itemChanged(self):
		self.setChecked(True)

class LGetMultiInfoDialog(KDialogBase):
	def __init__(self,tracks = None):
		self.tracks = tracks
		caption = i18n("Multiple Song Information")
		KDialogBase.__init__( self, None, "getmultiinfodialog", True, caption, KDialogBase.Ok+KDialogBase.Cancel, KDialogBase.Ok, True )
		self.makeArtistCompletion()
		self.makeAlbumCompletion()
		self.build()
		self.load()
		self.adjustSize()
		self.setFixedSize(self.size())
	
	def makeArtistCompletion(self):
		library = Library.mainLibrary()
		artists = library.artists()
		self.artistCompletion = KCompletion()
		self.artistCompletion.setOrder(KCompletion.Sorted)
		for artist in artists:
			self.artistCompletion.addItem(artist)
	
	def makeAlbumCompletion(self):
		library = Library.mainLibrary()
		albums = library.albums()
		self.albumCompletion = KCompletion()
		self.albumCompletion.setOrder(KCompletion.Sorted)
		for album in albums:
			self.albumCompletion.addItem(album)

	def build(self):
		page = QWidget(self)
		self.setMainWidget(page)
		layoutMain = QHBoxLayout(page)
		labelLayout= QVBoxLayout()
		layoutMain.addLayout(labelLayout,1)
		#add labels
		labelLayout.setSpacing(5)
		labelArtist=QLabel(i18n('<b>Artist</b>'),page)
		labelLayout.addWidget(labelArtist)
		labelAlbum=QLabel(i18n('<b>Album</b>'),page)
		labelLayout.addWidget(labelAlbum)
		labelGr=QLabel(i18n('<b>Genre</b>'),page)
		labelLayout.addWidget(labelGr)
		labelSpacer=QLabel(i18n(' '),page)
		labelLayout.addWidget(labelSpacer)
		labelTrk=QLabel(i18n('<b>Track</b>'),page)
		labelLayout.addWidget(labelTrk)
		labelGrp=QLabel(i18n('<b>Grouping</b>'),page)
		labelLayout.addWidget(labelGrp)
		labelCmp=QLabel(i18n('<b>Composer</b>'),page)
		labelLayout.addWidget(labelCmp)
		labelCmt=QLabel(i18n('<b>Comments</b>'),page)
		labelLayout.addWidget(labelCmt)
		labelBpm=QLabel(i18n('<b>BPM</b>'),page)
		labelLayout.addWidget(labelBpm)
		labelVol=QLabel(i18n('<b>Volume</b>'),page)
		labelLayout.addWidget(labelVol)
		labelRate=QLabel(i18n('<b>Rating</b>'),page)
		labelLayout.addWidget(labelRate)
		labelComp=QLabel(i18n('<b>Compilation</b>'),page)
		labelLayout.addWidget(labelComp)
		labelEq=QLabel(i18n('<b>Equalizer</b>'),page)
		labelLayout.addWidget(labelEq)
		layout=QVBoxLayout()
		layoutMain.addLayout(layout,2)
		layout.setSpacing(5)
##		labelSpacer=QLabel(i18n(' '),page)
##		labelLayout.addWidget(labelSpacer)
		labelLayout.addItem(QSpacerItem(1,3,QSizePolicy.Fixed,QSizePolicy.Fixed))
		
		self.buildCheckItem('artist',page,layout)
		self.artistEdit.setCompletionObject(self.artistCompletion)
		
		self.buildCheckItem('album',page,layout)
		self.albumEdit.setCompletionObject(self.albumCompletion)
		
		gy=QHBoxLayout()
		layout.addLayout(gy,2)
		self.buildGenreItem(page,gy)
		labelEq=QLabel(i18n('<b>Year</b>'),page)
		gy.addWidget(labelEq)
		self.buildSpinboxCheckItem('year',page,gy)
		
		lineLabel1=QLabel(" ",page)
		layout.addWidget(lineLabel1)
		lineLabel1.setFrameStyle(QFrame.HLine|QFrame.Sunken)
		
		td=QHBoxLayout()
		layout.addLayout(td,2)
		self.buildDualSpinCheckItem('track',None,page,td)
		self.buildDualSpinCheckItem('disc',i18n('Disc'),page,td)
		
		self.buildCheckItem('grouping',page,layout)
		self.buildCheckItem('composer',page,layout)
		self.buildCheckItem('comment',page,layout)
		
		ae=QHBoxLayout()
		layout.addLayout(ae,2)
		ve=QVBoxLayout()
		ae.addLayout(ve,2)
		self.buildCheckItem('bpm',page,ve)
		self.buildVolumeItem(page,ve)
		self.buildRatingItem(page,ve)
		self.buildCompilationItem(page,ve)
		self.buildEqualizerItem(page,ve)
		#ae.addItem(QSpacerItem(10,1,QSizePolicy.Fixed,QSizePolicy.Fixed))
		#ae.insertSpacing(1,30)
##		lineLabel1=QLabel(" ",page)
##		ae.addWidget(lineLabel1)
##		lineLabel1.setFrameStyle(QFrame.VLine|QFrame.Sunken)
		ae.insertSpacing(1,15)
		art=QVBoxLayout()
		ae.addLayout(art,2)
		self.buildArtworkItem(page,art)
		layoutMain.addItem(QSpacerItem(1,3,QSizePolicy.Fixed,QSizePolicy.Fixed))

	
	def buildCheckItem(self,name,container,containerLayout):
		layout = QHBoxLayout()
		containerLayout.addLayout(layout)
		hlayout = QHBoxLayout()
		layout.addLayout(hlayout)
		checkName = name+"Check"
		editName = name+"Edit"
		checkItem = LGetMultiInfoCheckBox(container)
		self.__dict__[checkName] = checkItem
		hlayout.addWidget(checkItem)
		editItem = KLineEdit("",container)
		self.__dict__[editName] = editItem
		hlayout.addWidget(editItem)
		checkItem.setLineEditItem(editItem)
		
	def buildSpinboxCheckItem(self,name,container,containerLayout):
		layout = QHBoxLayout()
		containerLayout.addLayout(layout)
		hlayout = QHBoxLayout()
		layout.addLayout(hlayout)
		checkName = name+"Check"
		editName = name+"Edit"
		checkItem = LGetMultiInfoCheckBox(container)
		self.__dict__[checkName] = checkItem
		hlayout.addWidget(checkItem)
		editItem = QSpinBox(1900,2100,1,container,'yrEdit')
		editItem.setSpecialValueText(' ')
		editItem.setMaximumWidth(100)
		self.__dict__[editName] = editItem
		hlayout.addWidget(editItem)
		checkItem.setSpinEditItem(editItem)
		
	def buildDualSpinCheckItem(self,name,labelText,container,containerLayout):
		layout = QHBoxLayout()
		containerLayout.addLayout(layout)
		if labelText is not None:
			label = QLabel(u"<b>%s</b>" % unikode(labelText),container)
			layout.insertSpacing(1,10)
			layout.addWidget(label)
		hlayout = QHBoxLayout()
		layout.addLayout(hlayout)
		checkNumName = name+"NumCheck"
		editNumName = name+"NumEdit"
		checkCountName = name+"CountCheck"
		editCountName = name+"CountEdit"
		checkItem = LGetMultiInfoCheckBox(container)
		self.__dict__[checkNumName] = checkItem
		hlayout.addWidget(checkItem)
		editItem = QSpinBox(0,100,1,container," from ")
		editItem.setSpecialValueText(' ')
		editItem.setMaximumWidth(80)
		self.__dict__[editNumName] = editItem
		editItem.setMinimumWidth(self.fontMetrics().maxWidth()*2)
		hlayout.addWidget(self.__dict__[editNumName])
		checkItem.setSpinEditItem(editItem)
		label = QLabel(i18n("of"),container)
		hlayout.addWidget(label)
		checkItem = LGetMultiInfoCheckBox(container)
		self.__dict__[checkCountName] = checkItem
		hlayout.addWidget(checkItem)
		editItem = QSpinBox(0,100,1,container," to ")
		editItem.setSpecialValueText(' ')
		editItem.setMaximumWidth(80)
		self.__dict__[editCountName] = editItem
		#editItem.setMinimumWidth(self.fontMetrics().maxWidth()*2)
		hlayout.addWidget(editItem)
		checkItem.setSpinEditItem(editItem)

		
	def buildArtworkItem(self,container,containerLayout):
		# XXX DSM build artwork well here
		layout=QHBox(container,'artFrame')
		layout.setFrameStyle(QFrame.Panel+QFrame.Sunken)
		layout.setLineWidth(1)
		layout.setMargin(5)
		containerLayout.addWidget(layout)
		self.artwork = ArtLabel(layout)
		self.artwork.setFrameStyle(QFrame.Box+QFrame.Plain)
		self.artwork.setLineWidth(1)
		self.artwork.setFixedSize(QSize(110,110))
		self.artwork.setPaletteBackgroundColor(QColor(255,255,255))
		self.artwork.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed)
		self.artwork.setAlignment(Qt.AlignCenter)
		self.artwork.setAcceptDrops(True)
		#layout.addWidget(self.artwork)
		layoutB=QVBox(layout,'btnLayout')
		layoutB.setMargin(3)
		#layout.addLayout(layoutB)
		self.artCheckBox=QCheckBox(i18n('Album Cover'),layoutB,'artChck')
		#layoutB.addWidget(self.artCheckBox)
		self.removeBtn = QPushButton(i18n("Remove"),layoutB,"remBtn")
		self.removeBtn.setFixedWidth(80)
		#layoutB.addWidget(self.removeBtn)
		QObject.connect(self.removeBtn,SIGNAL("released()"),self.removeArt)
		self.amazonLookUpButton = QPushButton(i18n("Fetch Art"),layoutB)
		self.amazonLookUpButton.setFixedWidth(80) 
		#layoutB.addWidget(self.amazonLookUpButton)
		QObject.connect(self.amazonLookUpButton,SIGNAL("released()"),self.amazonLookUp)
		#layout.show()

		
	def removeArt(self):
		self.artwork.img=None
		self.removeBtn.setEnabled(False)
		self.artCheckBox.setChecked(True)
		self.setDefault()
		
	def amazonLookUp(self):
		setLicense('D3523Y3ZHA0AZ5')
		srchStr=unikode(self.albumEdit.text())+" "+unikode(self.artistEdit.text())#+unikode(self.artistEdit.text())
		skip=False
		if self.compilationEdit.currentText()==i18n('Yes'):
			skip = True
		if srchStr=='':
			KMessageBox.error(self,"Please provide album name before looking up artwork","No Album Name")
			return 
		try:
			(pixmap,imgurl)=getAlbumArt(srchStr,'large')
		except:
			if self.artistEdit.text()!='' and not skip:
				try:
					srchStr=unikode(self.albumEdit.text())
					(pixmap,imgurl)=getAlbumArt(srchStr,'large')
				except:
					pixmap=None
					KMessageBox.error(self,"8traK could not find any artwork for this album","No artwrok available")
			else:
				pixmap=None
				KMessageBox.error(self,"8traK could not find any artwork for this album","No artwrok available")
		if pixmap is not None:
			#pixmap=QPixmap(resArt[0])
			self.artwork.setPixmap(fittedPixmap(pixmap,110,110))#item = QIconViewItem(self.artIconView,"",pixmap)
			self.artCheckBox.setChecked(True)
			self.removeBtn.setEnabled(True)
			f=open(imgurl,'rb')
			self.artwork.img=(f.read())
			f.close()

		
	def buildGenreItem(self,container,containerLayout):
		layout = QHBoxLayout()
		containerLayout.addLayout(layout)
		#label = QLabel(u"<b>%s</b)" % unikode(i18n("Genre")),container)
		#layout.addWidget(label)
		hlayout = QHBoxLayout()
		layout.addLayout(hlayout)
		self.genreCheck = LGetMultiInfoCheckBox(container)
		hlayout.addWidget(self.genreCheck)
		self.genreEdit = KComboBox(False,container)
		sortedGenres = musicGenres[:]
		sortedGenres.sort()
		for genre in sortedGenres:
			self.genreEdit.insertItem(genre)
		hlayout.addWidget(self.genreEdit,2)
		self.genreCheck.setComboBoxItem(self.genreEdit)
		
	def buildCompilationItem(self,container,containerLayout):
		layout = QHBoxLayout()
		containerLayout.addLayout(layout)
		#label = QLabel(u"<b>%s</b>" % unikode(i18n("Part of a Compilation")),container)
		#layout.addWidget(label)
		hlayout = QHBoxLayout()
		layout.addLayout(hlayout)
		self.compilationCheck = LGetMultiInfoCheckBox(container)
		hlayout.addWidget(self.compilationCheck)
		self.compilationEdit = KComboBox(False,container)
		self.compilationEdit.setFixedWidth(100)
		self.compilationEdit.insertItem(i18n('No'))
		self.compilationEdit.insertItem(i18n('Yes'))
		hlayout.addWidget(self.compilationEdit)
		self.compilationCheck.setComboBoxItem(self.compilationEdit)
		
	def buildRatingItem(self,container,containerLayout):
		layout = QHBoxLayout()
		containerLayout.addLayout(layout)
		#label = QLabel(u"<b>%s</b>" % unikode(i18n("Rating")),container)
		#layout.addWidget(label)
		hlayout = QHBoxLayout()
		layout.addLayout(hlayout)
		self.ratingCheck = LGetMultiInfoCheckBox(container)
		hlayout.addWidget(self.ratingCheck)
		self.ratingEdit = RatingWidget(container)
		self.ratingEdit.setFixedWidth(100)
		hlayout.addWidget(self.ratingEdit)
		self.ratingCheck.setRatingItem(self.ratingEdit)
		
	def buildVolumeItem(self,container,containerLayout):
		layout = QHBoxLayout()
		containerLayout.addLayout(layout)
#		label = QLabel(u"<b>%s</b>" % unikode(i18n("Volume Adjustment")),container)
#		layout.addWidget(label)
		hlayout = QHBoxLayout()
		layout.addLayout(hlayout)
		self.volumeCheck = LGetMultiInfoCheckBox(container)
		hlayout.addWidget(self.volumeCheck)
		self.volumeSlider = QSlider(Qt.Horizontal,container)
		self.volumeSlider.setMinValue(-100)
		self.volumeSlider.setMaxValue(100)
		self.volumeSlider.setTickmarks(QSlider.Below)
		self.volumeSlider.setTickInterval(10)
		hlayout.addWidget(self.volumeSlider)
		self.volumeCheck.setSliderItem(self.volumeSlider)
		
	def buildEqualizerItem(self,container,containerLayout):
		layout = QHBoxLayout()
		containerLayout.addLayout(layout)
		#label = QLabel(u"<b>%s</b>" % unikode(i18n("Equalizer")),container)
		#layout.addWidget(label)
		hlayout = QHBoxLayout()
		layout.addLayout(hlayout)
		self.equalizerCheck = LGetMultiInfoCheckBox(container)
		hlayout.addWidget(self.equalizerCheck)
		self.equalizerEdit = KComboBox(False,container)
		for preset in equalizerPresets:
			self.equalizerEdit.insertItem(preset['Label'])
		hlayout.addWidget(self.equalizerEdit)
		#hlayout.addItem(QSpacerItem(1,1,QSizePolicy.Expanding,QSizePolicy.Fixed))
		self.equalizerCheck.setComboBoxItem(self.equalizerEdit)
		
	def load(self):
		tags = None
		notMP3=False
		canWrite=True
		for track in self.tracks:
			if canWrite:
				try:
					f=open(track.location,'a')
					canWrite=True
					f.close()
				except:
					canWrite=False
			tags = track.loadTagsInto(tags)
			if track.kind!='MPEG audio file':
				notMP3=True
		#print "loading",tags
		if tags:
			items = ['artist','album','grouping','composer','comment',\
				'bpm']
			for item in items:
				itemEdit = self.__dict__[item+'Edit']
				itemEdit.blockSignals(True)
				item = tags.get(item,'')
				if type(item).__name__ in ['int','long']:
					item = str(item)
				itemEdit.setText(item)
				itemEdit.blockSignals(False)
			self.genreEdit.blockSignals(True)
			try: self.genreEdit.setCurrentText(str(tags.get('genre','')))
			except: pass
			self.genreEdit.blockSignals(False)
			spinItems = ['year','trackNum','trackCount','discNum','discCount']
			for item in spinItems:
				itemEdit = self.__dict__[item+'Edit']
				itemEdit.blockSignals(True)
				item = tags.get(item,'')
##				if type(item).__name__ in ['int','long']:
##					item = str(item)
				if item!='':
					itemEdit.setValue(item)
				itemEdit.blockSignals(False)
			self.volumeSlider.blockSignals(True)
			try: self.volumeSlider.setValue(tags.get('volume',0))
			except: pass
			self.volumeSlider.blockSignals(False)
			self.equalizerEdit.blockSignals(True)
			try: self.equalizerEdit.setCurrentText(str(tags.get('equalizer','')))
			except: pass
			self.equalizerEdit.blockSignals(False)
			self.compilationEdit.blockSignals(True)
			try:
				self.compilationEdit.setCurrentText('')
				if tags.get('compilation',''):
					self.compilationEdit.setCurrentText('Yes')
				else:
					self.compilationEdit.setCurrentText('No')
			except: pass
			self.compilationEdit.blockSignals(False)
			self.ratingCheck.blockSignals(True)
			try:
				self.ratingEdit.setRating(tags['rating'])
				self.ratingCheck.setChecked(False) # XXX DSM PyQt does not block python signals in this version
			except: pass
			self.ratingCheck.blockSignals(False)
			pixmap=None
			try:
				albumStr=tags['album']
				if albumStr!=None and albumStr!='':
					self.amazonLookUpButton.setEnabled(True)
					for track in self.tracks:
						self.artwork.img=track.image
						if self.artwork.img!= None:
							pixmap = QPixmap()
							pixmap.loadFromData(self.artwork.img)
							break
			except:
				self.artwork.img=None#self.artwork
				pixmap=None
			print "check pixmap",pixmap
			if pixmap != None:
				#self.artwork.setText("")
				self.artwork.setPixmap(fittedPixmap(pixmap,110,110))
				self.artCheckBox.setChecked(True)
				self.artwork.setEnabled(True)
				self.removeBtn.setEnabled(True)
			else:
				self.setDefault()	
				if self.albumEdit.text()=='' or notMP3:
					if notMP3:
						self.amazonLookUpButton.setEnabled(False)
						self.artCheckBox.setEnabled(False)
						self.artwork.setEnabled(False)
						self.artwork.setText(u"<font color='#C0C0C0'><b>%s</b></font>" % unikode(i18n("File format <br> does not support artwork")))
						self.removeBtn.setEnabled(False)
				else:
					self.amazonLookUpButton.setEnabled(True)
					self.artwork.setEnabled(True)
		else:
			if not canWrite:
				self.putWriteNote()
			self.setDefault()
			print "else"
		if not canWrite:
				self.putWriteNote()
	
	def putWriteNote(self):
		print "put write note"
		pass
	
	def setDefault(self):
		print "SET DEFAULT"
		self.artwork.setPixmap(fittedPixmap(QPixmap(art('artwork.png')),110,110))
		#self.artwork.setText(u"<font color='#C0C0C0'><b>%s</b></font>" % unikode(i18n("Drag Image Here<br>to set<br>Album Artwork")))
		self.removeBtn.setEnabled(False)

	def unload(self):
		tags = {}
		items = ['artist','album','grouping','composer','comment',\
			'year','trackNum','trackCount','discNum','discCount','bpm']
		for item in items:
			if self.__dict__[item+'Check'].isChecked():
				tags[item] = unikode(self.__dict__[item+'Edit'].text())
		if self.genreCheck.isChecked():
			tags['genre'] = str(self.genreEdit.currentText())
		if self.volumeCheck.isChecked():
			tags['volume'] = self.volumeSlider.value()
		if self.equalizerCheck.isChecked():
			tags['equalizer'] = str(self.equalizerEdit.currentText())
		if self.compilationCheck.isChecked():
			tags['compilation'] = self.compilationEdit.currentText()==i18n('Yes')
		if self.ratingCheck.isChecked():
			tags['rating'] = self.ratingEdit.rating()
		#if self.albumCoverURL is not None and self.artChanged:
		if self.artCheckBox.isChecked():
			tags['image']=self.artwork.img
		# XXX DSM handle artwork
		#print tags
		return tags

if __name__=="__main__":
	app = KApplication(sys.argv,"test")
	QObject.connect(app,SIGNAL('lastWindowClosed()'),app,SLOT('quit()'))
	dialog = LGetMultiInfoDialog()
	app.setMainWidget(dialog)
	dialog.show()
	app.exec_loop()
